#include "iconthemewidget.h"


bool IconThemeWidget::g_themeChange;
/**
 * @brief 构造函数
 *
 * 用于创建 IconThemeWidget 实例的构造函数。
 *
 * @param isHistory 是否为历史图标主题
 * @param parent 父 QWidget
 */
IconThemeWidget::IconThemeWidget(bool isHistory, QWidget *parent) : QWidget(parent)
{
    //是否存在导入素材QMap
    m_themeChangeMap = new QMap<QString, bool>();
    //历史记录中图标是否存在QMap
    m_iconPresenceMap = new QMap<QString, bool>();
    initMaps();
    initSystemMaps();
    initPreviewWidget();
    initRightWidget();
    QPushButton *line = new QPushButton();
    line->setDisabled(true);
    line->setFixedWidth(1);
    line->setFixedHeight(2000);
    QHBoxLayout * m_iconthemelayout = new QHBoxLayout();
    m_iconthemelayout->addWidget(m_previewwidget);
    m_iconthemelayout->addWidget(line);
    m_iconthemelayout->addWidget(m_rightwidget);

    m_iconthemelayout->setContentsMargins(0,0,0,0);
    m_iconthemelayout->setSpacing(0);

    this->setLayout(m_iconthemelayout);
}

/**
 * @brief 初始化预览小部件
 *
 * 创建一个QWidget作为预览小部件，并设置其最小大小、背景颜色等属性。
 * 创建一个QStackedWidget作为图片预览的容器。
 * 创建两个ImageWidget分别用于显示自定义图标和系统图标，并更新图标路径映射。
 * 将两个ImageWidget添加到QStackedWidget中。
 * 将QStackedWidget添加到布局中。
 * 连接壁纸更新信号，当壁纸更新时，更新预览小部件的图片。
 */
void IconThemeWidget::initPreviewWidget()
{
    m_previewwidget = new BasePreviewWidget(this);
    m_previewwidget->setMinimumSize(550,620);

    m_previewstack = new QStackedWidget(m_previewwidget);

    m_preview = new ImageWidget(m_previewwidget,m_iconpathmap);
    m_preview->updateIconMap(m_iconpathmap);
    m_systempreview = new ImageWidget(m_previewwidget,m_systemiconpathmap);
    m_previewstack->addWidget(m_preview);
    m_previewstack->addWidget(m_systempreview);
    QVBoxLayout *layout = new QVBoxLayout(m_previewwidget);

    QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
    QSpacerItem *spacer2 = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
    spacer->changeSize(m_previewwidget->width(), 155, QSizePolicy::Maximum, QSizePolicy::Maximum);
    spacer2->changeSize(m_previewwidget->width(), 159, QSizePolicy::Maximum, QSizePolicy::Maximum);
    connect(this,&IconThemeWidget::wallpaperupdate,  m_preview,[=](const QString& filePath){
        m_preview->updateImage(filePath);
    });
    layout->addItem(spacer);
    layout->addWidget(m_previewstack);
    layout->addItem(spacer2);

    m_previewwidget->setLayout(layout);
}

/**
 * @brief 初始化编辑小部件
 *
 * 初始化编辑小部件，并创建相应的控件和布局。
 */
void IconThemeWidget::initEditWidget()
{

    m_editwidget = new QWidget(m_stackedwidget);
    QScrollArea *m_scrollArea = new QScrollArea(m_rightwidget);
//    m_scrollArea->setFrameStyle(QFrame::HLine);
    m_scrollArea->setMinimumSize(m_editwidget->size());
    m_scrollArea->setWidgetResizable(true);
    QWidget *viewportWidget = new QWidget(m_scrollArea);
    m_scrollArea->setWidget(viewportWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(viewportWidget);
    viewportWidget->setLayout(mainLayout);

    for (auto it = m_iconpathmap->begin(); it != m_iconpathmap->end(); ++it) {
        const QString& widgetName = it.key();
        const QString& filePath = it.value();
        // 遍历每个图标插入默认false未导入状态
        m_themeChangeMap->insert(widgetName, false);
        IconEditWidget* widget = new IconEditWidget(viewportWidget);
        widget->setdefaulticon(filePath);
        widget->setdefaulticonname(widgetName);

        QPushButton *line = new QPushButton();
        line->setDisabled(true);
        line->setFixedHeight(1);

        mainLayout->addWidget(widget);
        mainLayout->addWidget(line);
        m_pathWidgetMap->insert(widgetName, widget);

        connect(widget->m_addiconbutton, &QPushButton::clicked, this, [=]() {
            QPushButton* clickedButton = qobject_cast<QPushButton*>(sender());

            if (clickedButton) {
                IconEditWidget* clickedWidget = nullptr;
                QWidget *widget = clickedButton->parentWidget();
                while (widget && !widget->inherits("IconEditWidget")) {
                    widget = widget->parentWidget();
                }
                clickedWidget = qobject_cast<IconEditWidget*>(widget);

                if (clickedWidget) {
                    QString newFilePath = QFileDialog::getOpenFileName(this, tr("Select SVG file"), QDir::homePath(), tr("SVG file (*.svg)"));

                    if (!newFilePath.isEmpty()) {
                        m_customiconpathmap->insert(widgetName, newFilePath);
                        clickedWidget->setcustomicon(newFilePath);
                        m_preview->updateIcon(widgetName, newFilePath);
                        //导入成功图标修改QMap状态true
                        m_themeChangeMap->insert(widgetName, true);
                        // 传递当前主题变化信号
                        emit iconthemeChange(m_themeChangeMap);
                    }
                    emit newAppIconsMap(m_customiconpathmap);
                }
            }
        });
        connect(widget,&IconEditWidget::deleteCustomIcon,this,[=](){
            QString iconPath = ":/resource/appicons/"+widgetName+".png";
            m_preview->updateIcon(widgetName, iconPath);
            m_customiconpathmap->insert(widgetName, iconPath);
            emit newAppIconsMap(m_customiconpathmap);
            if (m_info.historytime == nullptr){
                m_themeChangeMap->insert(widgetName, false);
            }else{
                if(m_iconPresenceMap->value(widgetName)){
                    m_themeChangeMap->insert(widgetName, true);
                    m_iconPresenceMap->insert(widgetName, false);
                }else{
                    m_themeChangeMap->insert(widgetName, false);
                }
            }
            emit iconthemeChange(m_themeChangeMap);
        });
    }

    QVBoxLayout *mainWidgetLayout = new QVBoxLayout(m_editwidget);
    mainWidgetLayout->addWidget(m_scrollArea);
    m_editwidget->setLayout(mainWidgetLayout);
}

/**
 * @brief 更新自定义图标路径映射
 *
 * 清空现有的 m_customiconpathmap，将 historyMap 中的数据复制到 m_customiconpathmap，
 * 并更新相应的图标和预览。
 *
 * @param historyMap 自定义图标路径历史的 QMap 指针
 */
void IconThemeWidget::updateCustomIconPathMap(QMap<QString, QString>*historyMap)
{
    // 清空现有的 m_customiconpathmap
    m_customiconpathmap->clear();

    // 将 historyMap 中的数据复制到 m_customiconpathmap
    m_customiconpathmap = historyMap;

    // 更新相应的图标和预览
    for (auto it = m_pathWidgetMap->begin(); it != m_pathWidgetMap->end(); ++it) {
        const QString& widgetName = it.key();
        IconEditWidget* widget = it.value();

        // 遍历每个图标插入默认false未导入状态以及插入无图标内容false状态
        m_themeChangeMap->insert(widgetName, false);
        m_iconPresenceMap->insert(widgetName, false);
        widget->setcustomicon(NULL);
        // 检查 m_customiconpathmap 中是否存在当前的 widgetName
        if (m_customiconpathmap->contains(widgetName)) {
            const QString& filePath = m_customiconpathmap->value(widgetName);

            // 判断文件类型为svg才显示
            QFileInfo fileInfo(filePath);
            if (fileInfo.suffix().toLower() == "svg") {
                widget->setcustomicon(filePath);
                m_preview->updateIcon(widgetName, filePath);
                //插入图标内容存在状态true
                m_iconPresenceMap->insert(widgetName, true);
            } else {
                // 如果文件类型不是svg，直接跳过并不显示
                continue;
            }
        }
    }
}

/**
 * @brief 更新自定义系统图标路径映射
 *
 * 根据给定的历史图标路径映射，更新自定义系统图标路径映射。
 *
 * @param historyMap 历史图标路径映射指针
 */
void IconThemeWidget::updateCustomSyetemIconPathMap(QMap<QString, QString>*historyMap)
{
    m_systemcustomiconpathmap->clear();

    m_systemcustomiconpathmap = historyMap;

    for (auto it = m_systempathWidgetMap->begin(); it != m_systempathWidgetMap->end(); ++it) {
        const QString& widgetName = it.key();
        IconEditWidget* widget = it.value();
        m_themeChangeMap->insert(widgetName, false);
        m_iconPresenceMap->insert(widgetName, false);
        widget->setcustomicon(NULL);

        if (m_systemcustomiconpathmap->contains(widgetName)) {
            m_themeChangeMap->insert(widgetName, false);
            m_iconPresenceMap->insert(widgetName, false);
            const QString& filePath = m_systemcustomiconpathmap->value(widgetName);

            // 判断文件类型为svg才显示
            QFileInfo fileInfo(filePath);
            if (fileInfo.suffix().toLower() == "svg") {
                widget->setcustomicon(filePath);
                m_preview->updateIcon(widgetName, filePath);
                m_iconPresenceMap->insert(widgetName, true);
            }
            else {
                // 如果文件类型不是svg，直接跳过并不显示
                continue;
            }
        }
    }
}

/**
 * @brief 初始化系统编辑控件
 *
 * 初始化系统编辑控件，并创建相应的子控件。
 */
void IconThemeWidget::initSystemEditWidget()
{
    m_systemeditwidget = new QWidget(m_stackedwidget);
    QScrollArea *m_systemscrollArea = new QScrollArea(m_rightwidget);
//    m_systemscrollArea->setFrameStyle(QFrame::HLine);
    m_systemscrollArea->setWidgetResizable(true);
    QWidget *viewportWidget = new QWidget(m_systemscrollArea);
    m_systemscrollArea->setWidget(viewportWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(viewportWidget);
    viewportWidget->setLayout(mainLayout);


    for (auto it = m_systemiconpathmap->begin(); it != m_systemiconpathmap->end(); ++it) {
        const QString& widgetName = it.key();
        const QString& filePath = it.value();
        IconEditWidget* widget = new IconEditWidget(viewportWidget);
        widget->setdefaulticon(filePath);
        widget->setdefaulticonname(widgetName);
        QPushButton *line = new QPushButton();
        line->setDisabled(true);
        line->setFixedHeight(1);

        mainLayout->addWidget(widget);
        mainLayout->addWidget(line);

        m_systempathWidgetMap->insert(widgetName, widget);

        // 当widget中的"添加图标"按钮被点击时，执行下面的函数。
        connect(widget->m_addiconbutton, &QPushButton::clicked, this, [=]() {

            // 获取发出信号的按钮，并将其转换为QPushButton*类型。
            QPushButton* clickedButton = qobject_cast<QPushButton*>(sender());
            // 检查转换是否成功。如果成功，继续执行下面的代码。
            if (clickedButton) {
                // 定义一个IconEditWidget类型的指针变量，并将其初始化为nullptr。
                IconEditWidget* clickedWidget = nullptr;
                // 获取点击的按钮的父窗口，并将其作为QWidget类型保存。
                QWidget *widget = clickedButton->parentWidget();
                
                // 循环遍历父窗口，直到找到一个窗口是IconEditWidget类型的窗口。
                while (widget && !widget->inherits("IconEditWidget")) {
                    widget = widget->parentWidget();
                }
                // 将QWidget类型转换为IconEditWidget类型，并将结果保存到clickedWidget变量中。
                clickedWidget = qobject_cast<IconEditWidget*>(widget);
                // 检查转换是否成功。如果成功，继续执行下面的代码。
                if (clickedWidget) {
                    
                    // 显示一个文件选择对话框，让用户选择一个SVG文件。将文件路径保存到newFilePath变量中。
                    QString newFilePath = QFileDialog::getOpenFileName(this, tr("Select SVG file"), QDir::homePath(), tr("SVG file (*.svg)"));
                    if (!newFilePath.isEmpty()) {
                        //check
                        if(FileCheck::isLegalIconFile(newFilePath)){
                            // 将新的文件路径插入到m_systemcustomiconpathmap中，键为widgetName。
                            m_systemcustomiconpathmap->insert(widgetName, newFilePath);
                            // 设置clickedWidget的自定义图标为新的文件路径。
                            clickedWidget->setcustomicon(newFilePath);
                            
                            // 输出选择的文件路径和对应的widgetName。
                            qDebug() << "Selected file path:" << newFilePath<< "Corresponding widgetName:" << widgetName;
                            // 更新系统预览图标的显示。
                            m_systempreview->updateIcon(widgetName, newFilePath);
                        }
                    }
                    // 发出一个新的系统图标映射信号。
                    emit newSystemIconsMap(m_systemcustomiconpathmap);
                }
            }
        });
        connect(widget,&IconEditWidget::deleteCustomIcon,this,[=](){
            QString iconPath = ":/resource/systemicons/"+widgetName+".png";
            m_systempreview->updateIcon(widgetName, iconPath);
            m_systemcustomiconpathmap->insert(widgetName, iconPath);
            emit newSystemIconsMap(m_systemcustomiconpathmap);
        });
    }

    QVBoxLayout *mainWidgetLayout = new QVBoxLayout(m_systemeditwidget);
    mainWidgetLayout->addWidget(m_systemscrollArea);
    m_systemeditwidget->setLayout(mainWidgetLayout);
}

/**
 * @brief 从目录中获取文件列表的widget名称
 *
 * 从指定的目录中获取文件列表，并返回包含文件名称的widget名称列表。
 *
 * @param directoryPath 目录路径
 *
 * @return widget名称列表
 */
QStringList IconThemeWidget::getWidgetNamesFromFilesInDirectory(const QString& directoryPath) {
    QStringList widgetNames;
    QDir dir(directoryPath);

    QStringList fileNames = dir.entryList(QDir::Files);
    foreach (const QString& fileName, fileNames) {
        QFileInfo fileInfo(fileName);
        QString widgetName = fileInfo.baseName();
        widgetNames.append(widgetName);
    }

    return widgetNames;
}

/**
 * @brief 初始化应用程序图标地图
 *
 * 初始化应用程序图标地图。
 */
void IconThemeWidget::initMaps()
{
    getResourcesAppIconMap("appicon");

    m_customiconpathmap = m_iconpathmap;
    m_pathWidgetMap = new QMap<QString, IconEditWidget*>;
}

/**
 * @brief 获取资源应用程序图标映射
 *
 * 根据给定的类型获取资源应用程序图标映射。
 *
 * @param Type 图标类型
 *
 * @return 返回 QMap<QString, QString> 指针，指向应用程序图标映射
 */
QMap<QString, QString> *IconThemeWidget::getResourcesAppIconMap(QString Type)
{
    if("appicon" == Type){
        m_iconpathmap = new QMap<QString, QString>;
        QString directoryPath = ":/resource/appicons/";
        QStringList widgetNames = getWidgetNamesFromFilesInDirectory(directoryPath);
        for (int i = 0; i < widgetNames.size(); ++i) {
            QString cursorFileName = directoryPath + widgetNames[i] + ".png";
            m_iconpathmap->insert(widgetNames[i], cursorFileName);
        }
        return m_iconpathmap;
    }else if("systemicon" == Type){
        m_systemiconpathmap = new QMap<QString, QString> ;
        QString directoryPath = ":/resource/systemicons/";
        QStringList widgetNames = getWidgetNamesFromFilesInDirectory(directoryPath);

        for (int i = 0; i < widgetNames.size(); ++i) {
            QString cursorFileName = directoryPath + widgetNames[i] + ".png";
            m_systemiconpathmap->insert(widgetNames[i], cursorFileName);
        }
        return m_systemiconpathmap;
    }

}

/**
 * @brief 初始化系统图标主题
 *
 * 初始化系统图标主题，包括获取系统应用图标映射和系统自定义图标路径映射，并创建新的 QMap 对象用于存储图标编辑小部件。
 */
void IconThemeWidget::initSystemMaps()
{
    //解决历史记录三次之后第单数历史记录窗出现段错误
    getResourcesAppIconMap("systemicon");

    m_systemcustomiconpathmap= m_systemiconpathmap;
    m_systempathWidgetMap = new QMap<QString, IconEditWidget*>;
}

/**
 * @brief 初始化右侧小部件
 *
 * 初始化右侧的子小部件，包括更换图标按钮、编辑图标和系统图标编辑页面以及堆叠式控件。
 */
void IconThemeWidget::initRightWidget()
{
    m_rightwidget = new QWidget(this);
    m_rightwidget->setMinimumSize(400,620);
    m_rightwidget->setMaximumWidth(400);


    m_rightwidgetlayout = new QVBoxLayout(m_rightwidget);

    QWidget *m_changebuttonwidget = new QWidget(m_rightwidget);
    m_changebuttonwidget->setMinimumSize(400,70);
    QHBoxLayout *layout = new QHBoxLayout();

    m_tabbar = new kdk::KTabBar();
    m_tabbar->setTabBarStyle(kdk::KTabBarStyle::SegmentDark);
    m_tabbar->addTab("AppIcons");
    m_tabbar->addTab("SystemIcons");

    layout->addWidget(m_tabbar);
    layout->setContentsMargins(0,0,15,0);
    m_changebuttonwidget->setLayout(layout);

    m_stackedwidget = new QStackedWidget(m_rightwidget);

    initEditWidget();
    initSystemEditWidget();
    m_stackedwidget->addWidget(m_editwidget);
    m_stackedwidget->addWidget(m_systemeditwidget);

    m_stackedwidget->setCurrentIndex(0);

    connect(m_tabbar, &QTabBar::tabBarClicked, [=](int tabIndex){
        m_stackedwidget->setCurrentIndex(tabIndex);
        m_previewstack->setCurrentIndex(tabIndex);
    });

    m_rightwidgetlayout->addWidget(m_changebuttonwidget);
    m_rightwidgetlayout->addWidget(m_stackedwidget);

    m_rightwidget->setLayout(m_rightwidgetlayout);
}

/**
 * @brief 获取应用图标的 QMap 对象
 *
 * 返回一个 QMap 对象，该对象包含了应用图标的键值对。
 * 用于刷新
 * @return 应用图标的 QMap 对象指针
 */
QMap<QString, QString>* IconThemeWidget::getAppIconsMap()
{
    getResourcesAppIconMap("appicon");
    return m_iconpathmap;
}

/**
 * @brief 获取系统图标映射表
 *
 * 获取系统图标映射表，返回一个 QMap 对象，其中键为图标名称，值为图标路径。
 * 用于刷新
 * @return 系统图标映射表
 */
QMap<QString, QString> *IconThemeWidget::getSystemIconsMap()
{
    getResourcesAppIconMap("systemicon");
    return m_systemiconpathmap;
}

/**
 * @brief 设置应用图标的浏览历史记录
 *
 * 根据指定的目录路径，浏览并加载该目录下所有的应用图标文件，并将它们保存到浏览历史记录中。
 */
void IconThemeWidget::setHistoryAppIcon()
{
    QString directoryPath = m_info.filepath + "/src/iconTheme/appicon/";
//    QStringList widgetNames = getWidgetNamesFromFilesInDirectory(directoryPath);
    QDir directory(directoryPath);
    QStringList filters;
    filters << "*.png" << "*.svg";
    QStringList fileList = directory.entryList(filters, QDir::Files);

    m_historyiconmap = new QMap<QString, QString>;


    foreach (const QString& fileName, fileList) {
        QString filePath = directoryPath + fileName;  // 使用文件名构建文件路径
        QString name = fileName.left(fileName.lastIndexOf('.'));
        m_historyiconmap->insert(name, filePath);
    }
}

/**
 * @brief 设置历史系统图标
 *
 * 从指定路径加载系统图标，并存储在历史系统图标映射中。
 */
void IconThemeWidget::setHistorySystemIcon()
{
    QString directoryPath = m_info.filepath + "/src/iconTheme/systemicon/";
    QDir directory(directoryPath);
    QStringList filters;
    filters << "*.png" << "*.svg";
    QStringList fileList = directory.entryList(filters, QDir::Files);

    m_historysystemiconmap = new QMap<QString, QString>;


    foreach (const QString& fileName, fileList) {
        QString filePath = directoryPath + fileName;  // 使用文件名构建文件路径
        QString name = fileName.left(fileName.lastIndexOf('.'));
        m_historysystemiconmap->insert(name, filePath);
    }
}
/**
 * @brief 初始化小部件
 *
 * 使用给定的历史信息数据初始化小部件。
 *
 * @param InfoData 历史信息数据对象
 */
void IconThemeWidget::eidtInitWidget(const HistoryInfo &InfoData)
{
    m_info = InfoData;
    setHistoryAppIcon();
    setHistorySystemIcon();
    m_preview->updateIconMap(m_historyiconmap);
    m_systempreview->updateIconMap(m_historysystemiconmap);
    updateCustomIconPathMap(m_historyiconmap);
    updateCustomSyetemIconPathMap(m_historysystemiconmap);
    if(m_info.wallpaperpath != nullptr){
        m_preview->updateImage(m_info.wallpaperpath);
    }else{
        m_preview->updateImage(":/resource/background/1-openkylin.jpg");
    }

}

/**
 * @brief 刷新图标主题部件
 *
 * 更新图标主题部件的预览图标映射和自定义图标路径映射。
 */
void IconThemeWidget::refresh()
{
    m_preview->updateIconMap(getResourcesAppIconMap("appicon"));
    updateCustomIconPathMap(m_iconpathmap);
    m_systempreview->updateIconMap(getResourcesAppIconMap("systemicon"));
    updateCustomSyetemIconPathMap(m_systemiconpathmap);

}
